/**
 * 代码中的类名、方法名、参数名已经指定，请勿修改，直接返回方法规定的值即可
 *
 * 
 * @param str string字符串 
 * @param pattern string字符串 
 * @return bool布尔型
 */
 function match( str ,  pattern ) {
  // write code here
  // 首先获取两个字符串的长度 分别记为m和n
  var m = str.length
  var n = pattern.length
  // 然后初始化我们的二维数组 初始化都是false
  var match = new Array(m+1).fill(0).map(v => new Array(n+1).fill(0))
  // for(let i = 0;i < m+1;i++){
  //   var temp = []
  //   for(let j = 0;j < n+1;j++){
  //     temp.push(false)
  //   }
  //   match.push(temp)
  // }
  // 然后我们从头开始计算这个二维数组
  for(let i = 0;i < m+1;i++){
    for(let j = 0;j < n+1;j++){
      // 首先考虑他这个边缘的情况 当p是一个空字符串的时候
      if(j === 0){
        if(i === 0){
          match[i][j] = true // match[i][j] 表示str的前i个字符和pattern的前j个字符是否匹配的问题 所以说i==0 j===0的时候就是s和p都是空串的时候
        }
        // j===0 i!==0 的其他情况下 都是false
      }else{
        // p不是空串的时候 这个时候就要计算
        // 我们在意的是p的最后一个字符 也就是p[j-1] j可以取到n n-1就是最后一个字符
        if(pattern[j-1] !== '*'){
          // 当最后一个字符不是星号的时候 只有当s的最后一个字符和p的最后一个字符相等的时候才是匹配的
          if(i>=1 && (str[i-1] === pattern[j-1] || pattern[j-1] === '.')){ //首先我们还得确保s至少有一个字符 这里因为是它的前j个和前i个字符 可以就把i和j当成是当前我们计算的这个子串的长度 i是0 也说明他有一个字符串啊
            // 同时s和j的做好一个字符时相等的 
            // 或者这个p的最后一个字符是可以匹配任何字符的一个点
            // 在这样的情况下呢 前i个字符和前j个字符的匹配问题 是 等于计算 前(i-1) 和 前(j-1)是否匹配的问题
            match[i][j] = match[i-1][j-1] // 这个的意思就是 最后一个字符已经匹配了 就判断前面的字符是否匹配的问题 
            // 如果说上一个if条件不满足的话  下面的是不会被执行的 那么match[i][j] 依然是初始化的值fasle 不匹配的  
          }
        }else{
          // 另一种情况 也就是说p[j-1]是星号的时候
          // 这个时候我们分为两种情况
          // 第一种情况就是p[j-1]和他前一个字符两个组合起来 我们把它给忽略掉 让他前一个字符给重复0次
          // 但是这种情况下我们得确保 这个p字符的长度至少是为2的
          if(j >= 2){
            // 重复0次
            match[i][j] |= match[i][j-2]
            // 重复大于0次
            if((j >= 2 && i >= 1) && ((str[i-1] === pattern[j-2]) || pattern[j-2] === '.')){ // p这个字符至少有两位并且i这个字符至少得有一位 才可以讨论匹配的问题 
              // 在什么情况下他可能是匹配的呢 ==> 那就是s的末尾和p的星号键前一位是相等的情况下 或者 p[j-2]是一个可以匹配任意字符的点 这两种情况下 他是有可能匹配的 我们就让他和s的最后一位匹配了 
              match[i][j] |= match[i-1][j] //因为p的最后两位字符代表了重复的过程 所以他在下一个s更短的子串里面是可以使用的所以是不会变的 还是结尾字符
            }
          }
        }
      }
    }
  }
  // 最后的最后 返回s的前m个字符 和p的前n个字符是否匹配
  return match[m][n]
}
module.exports = {
  match : match
};